<template>
  <el-dialog
    :title="formData.id ? '编辑接口' : '新建接口'"
    v-model="dialogVisible"
    width="800px"
    @close="handleClose"
  >
    <el-form
      ref="formRef"
      :model="formData"
      :rules="rules"
      label-width="120px"
      label-position="right"
    >
      <el-tabs v-model="activeTab">
        <el-tab-pane label="基本信息" name="basic">
          <el-form-item label="接口名称" prop="name">
            <el-input v-model="formData.name" placeholder="请输入接口名称" />
          </el-form-item>
          <el-form-item label="请求路径" prop="path">
            <el-input v-model="formData.path" placeholder="请输入请求路径" />
          </el-form-item>
          <el-form-item label="请求方法" prop="method">
            <el-select
              v-model="formData.method"
              placeholder="请选择请求方法"
              style="width: 100%"
            >
              <el-option
                v-for="method in Object.values(ApiMethod)"
                :key="method"
                :label="method"
                :value="method"
              />
            </el-select>
          </el-form-item>
          <el-form-item label="接口类型" prop="type">
            <el-select
              v-model="formData.type"
              placeholder="请选择接口类型"
              style="width: 100%"
            >
              <el-option
                v-for="type in Object.values(ApiType)"
                :key="type"
                :label="getApiTypeLabel(type)"
                :value="type"
              />
            </el-select>
          </el-form-item>
          <el-form-item
            v-if="formData.type === ApiType.DataSource"
            label="数据源"
            prop="dataSourceId"
          >
            <el-select
              v-model="formData.dataSourceId"
              placeholder="请选择数据源"
              style="width: 100%"
            >
              <el-option
                v-for="ds in dataSources"
                :key="ds.id!"
                :label="ds.name"
                :value="ds.id"
              />
            </el-select>
          </el-form-item>
          <el-form-item label="接口描述" prop="description">
            <el-input
              v-model="formData.description"
              type="textarea"
              :rows="3"
              placeholder="请输入接口描述"
            />
          </el-form-item>
        </el-tab-pane>

        <el-tab-pane label="接口配置" name="config">
          <!-- 数据源类型配置 -->
          <template v-if="formData.type === ApiType.DataSource">
            <el-form-item label="SQL语句" prop="config.sql">
              <monaco-editor
                v-model="sqlConfig.sql"
                language="sql"
                :height="200"
              />
            </el-form-item>
            <el-form-item label="参数配置" prop="config.params">
              <monaco-editor
                v-model="sqlParamsStr"
                language="json"
                :height="150"
                @change="handleSqlParamsChange"
              />
              <div v-if="sqlParamsError" class="json-error">
                {{ sqlParamsError }}
              </div>
            </el-form-item>
          </template>

          <!-- REST类型配置 -->
          <template v-else>
            <el-form-item label="请求URL" prop="config.url">
              <el-input
                v-model="restConfig.url"
                placeholder="请输入完整的URL地址"
              />
            </el-form-item>
            <el-form-item label="请求方法" prop="config.method">
              <el-select
                v-model="restConfig.method"
                placeholder="请选择请求方法"
                style="width: 100%"
              >
                <el-option
                  v-for="method in Object.values(ApiMethod)"
                  :key="method"
                  :label="method"
                  :value="method"
                />
              </el-select>
            </el-form-item>
            <el-form-item label="请求头" prop="config.headers">
              <monaco-editor
                v-model="restHeadersStr"
                language="json"
                :height="150"
                @change="handleRestHeadersChange"
              />
              <div v-if="restHeadersError" class="json-error">
                {{ restHeadersError }}
              </div>
            </el-form-item>
            <el-form-item label="请求参数" prop="config.params">
              <monaco-editor
                v-model="restParamsStr"
                language="json"
                :height="150"
                @change="handleRestParamsChange"
              />
              <div v-if="restParamsError" class="json-error">
                {{ restParamsError }}
              </div>
            </el-form-item>
            <el-form-item label="请求体" prop="config.body">
              <monaco-editor
                v-model="restConfig.body"
                language="json"
                :height="200"
              />
            </el-form-item>
          </template>
        </el-tab-pane>

        <el-tab-pane label="参数定义" name="schema">
          <el-form-item label="请求参数" prop="requestSchema">
            <monaco-editor
              v-model="formData.requestSchema"
              language="json"
              :height="200"
            />
          </el-form-item>
          <el-form-item label="返回结构" prop="responseSchema">
            <monaco-editor
              v-model="formData.responseSchema"
              language="json"
              :height="200"
            />
          </el-form-item>
        </el-tab-pane>
      </el-tabs>
    </el-form>

    <template #footer>
      <span class="dialog-footer">
        <el-button @click="handleClose">取消</el-button>
        <el-button type="primary" @click="handleSubmit" :loading="submitting">
          确定
        </el-button>
      </span>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
import { ref, reactive, computed, watch, onMounted } from "vue";
import type { FormInstance, FormRules } from "element-plus";
import { ElMessage } from "element-plus";
import MonacoEditor from "@/components/MonacoEditor.vue";
import type { ApiConfig } from "@/types/api";
import {
  ApiMethod,
  ApiStatus,
  ApiType,
  type SqlConfig,
  type RestConfig,
} from "@/types/api";
import type { DataSource } from "@/types/dataSource";
import { getDataSourceList } from "@/api/dataSource";

const props = defineProps<{
  visible: boolean;
  editData?: ApiConfig;
}>();

const emit = defineEmits<{
  (e: "update:visible", value: boolean): void;
  (e: "submit", data: ApiConfig): void;
}>();

const dialogVisible = computed({
  get: () => props.visible,
  set: (val) => emit("update:visible", val),
});

const formRef = ref<FormInstance>();
const submitting = ref(false);
const activeTab = ref("basic");
const dataSources = ref<DataSource[]>([]);
const sqlConfig = reactive<SqlConfig>({ sql: "" });
const restConfig = reactive<RestConfig>({
  url: "",
  method: ApiMethod.GET,
});

const sqlParamsStr = ref("{}");
const sqlParamsError = ref("");
const restHeadersStr = ref("{}");
const restHeadersError = ref("");
const restParamsStr = ref("{}");
const restParamsError = ref("");

const defaultForm: Omit<ApiConfig, "id"> = {
  name: "",
  path: "",
  method: ApiMethod.GET,
  status: ApiStatus.Enabled,
  description: "",
  dataSourceId: 0,
  requestSchema: "{\n  \n}",
  responseSchema: "{\n  \n}",
  type: ApiType.DataSource,
};

const formData = reactive<ApiConfig>({ ...defaultForm });

const rules: FormRules = {
  name: [{ required: true, message: "请输入接口名称", trigger: "blur" }],
  path: [{ required: true, message: "请输入请求路径", trigger: "blur" }],
  method: [{ required: true, message: "请选择请求方法", trigger: "change" }],
  dataSourceId: [
    { required: true, message: "请选择数据源", trigger: "change" },
  ],
};

const getApiTypeLabel = (type: ApiType) => {
  const labels: Record<ApiType, string> = {
    [ApiType.DataSource]: "数据源接口",
    [ApiType.REST]: "REST接口",
  };
  return labels[type];
};

const loadDataSources = async () => {
  try {
    const { list } = await getDataSourceList({
      page: 1,
      pageSize: 1000,
    });
    dataSources.value = list;
  } catch (error) {
    console.error("加载数据源列表失败:", error);
  }
};

const handleJsonChange = (
  value: string,
  errorRef: Ref<string>,
  callback: (parsed: any) => void
) => {
  try {
    const parsed = JSON.parse(value);
    errorRef.value = "";
    callback(parsed);
  } catch (error) {
    errorRef.value = "JSON格式错误";
  }
};

const handleSqlParamsChange = (value: string) => {
  handleJsonChange(value, sqlParamsError, (parsed) => {
    sqlConfig.params = parsed;
  });
};

const handleRestHeadersChange = (value: string) => {
  handleJsonChange(value, restHeadersError, (parsed) => {
    restConfig.headers = parsed;
  });
};

const handleRestParamsChange = (value: string) => {
  handleJsonChange(value, restParamsError, (parsed) => {
    restConfig.params = parsed;
  });
};

watch(
  () => props.editData,
  (newVal) => {
    if (newVal) {
      Object.assign(formData, newVal);
    } else {
      Object.assign(formData, defaultForm);
    }
  },
  { immediate: true }
);

const handleClose = () => {
  dialogVisible.value = false;
  formRef.value?.resetFields();
  Object.assign(formData, defaultForm);
  sqlParamsError.value = "";
  restHeadersError.value = "";
  restParamsError.value = "";
  activeTab.value = "basic";
};

const handleSubmit = async () => {
  if (!formRef.value) return;

  if (sqlParamsError.value || restHeadersError.value || restParamsError.value) {
    ElMessage.error("请修正JSON格式错误");
    return;
  }

  await formRef.value.validate((valid) => {
    if (valid) {
      submitting.value = true;
      try {
        if (formData.type === ApiType.DataSource) {
          formData.config = { ...sqlConfig };
        } else {
          formData.config = { ...restConfig };
        }
        emit("submit", { ...formData });
        handleClose();
      } finally {
        submitting.value = false;
      }
    }
  });
};

onMounted(() => {
  loadDataSources();
});
</script>

<style scoped>
.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
}

.json-error {
  color: #f56c6c;
  font-size: 12px;
  margin-top: -15px;
  margin-bottom: 15px;
  padding-left: 120px;
}

:deep(.el-tabs__content) {
  overflow: visible;
}
</style> 